package solutions.ferpa.ztest.intf;

import br.com.telescope.adsrt.dom.DomFileUpload;
import br.com.telescope.adsrt.dom.DomFlag;
import br.com.telescope.adsrt.dom.DomInteger;
import br.com.telescope.adsrt.dom.DomSourceCode;
import br.com.telescope.adsrt.dom.DomText;
import br.com.telescope.adsrt.lib.*;
import br.com.telescope.t2.ServiceModel;
import br.com.telescope.t2.UserAction;
import br.com.telescope.t2.config.Config;
import br.com.telescope.t2.exception.ApplicationRuntimeException;
import br.com.telescope.t2.exception.Severity;
import br.com.telescope.t2.exception.UnexpectedException;
import br.com.telescope.t2.feature.CustomActionFeature;
import br.com.telescope.t2.feature.CustomFeature;
import br.com.telescope.t2.feature.MethodFeature;
import br.com.telescope.t2.view.ActionRenderer;
import br.com.telescope.util.FileUtil;
import br.com.telescope.util.MimeType;
import br.com.telescope.util.TextUtil;
import br.com.telescope.util.ZipUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import javax.servlet.ServletOutputStream;
import solutions.ferpa.ztest.ent.*;

/**
 * Manutenção de arquivos.
 * <p>
 * É possível nesta interface acessar pelo botão "Pasta Apps" a pasta 
 * Apps, além de ordenar os arquivos pelo nome.
 * <P>
 * Telescope origin: RTCONFIG.UTL_FILES
 * <P>
 * @author TELESCOPE - Build task T2 Web Interface Generator
 * <P>
 * @version 0.1
 */
public class UtlFiles extends ServiceModel {
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    public static final String GLOBAL_NAME = "RTCONFIG.UTL_FILES";
    
    @Override
    public String globalName() {
        return GLOBAL_NAME;
    }
    
    {
        setTitle("Manutenção de arquivos");
    }
    
    
    // Record items
    private DomText aArquivo;
    private DomText aNomeArquivo;
    private DomText aTamanho;
    private DomText aDestino;
    private DomFileUpload aArquivoUpload;
    private DomSourceCode aConteudoArquivo;
    private DomText aDiretorio;
    private DomFlag aSubstituirArquivo;
    private DomText aCaminhoArquivo;
    
    // Query items
    
    @Override
    public void initAttributes() {
        
        aArquivo = new DomText();
        aArquivo.context(ctx).name("ARQUIVO").label("Arquivo").unbound(true);
        
        aNomeArquivo = new DomText();
        aNomeArquivo.context(ctx).name("NOME_ARQUIVO").label("Nome do arquivo").unbound(true);
        
        aTamanho = new DomText();
        aTamanho.context(ctx).name("TAMANHO").label("Tamanho").unbound(true);
        
        aDestino = new DomText();
        aDestino.context(ctx).name("DESTINO").label("Destino").width(50).unbound(true);
        
        aArquivoUpload = new DomFileUpload();
        aArquivoUpload.context(ctx).name("ARQUIVO_UPLOAD").label("Arquivo").format("multiple:true").unbound(true);
        
        aConteudoArquivo = new DomSourceCode();
        aConteudoArquivo.context(ctx).name("CONTEUDO_ARQUIVO").label("Conteudo").unbound(true);
        
        aDiretorio = new DomText();
        aDiretorio.context(ctx).name("DIRETORIO").label("Diretório").width(50).unbound(true);
        
        aSubstituirArquivo = new DomFlag();
        aSubstituirArquivo.context(ctx).name("SUBSTITUIR_ARQUIVO").label("Substituir arquivo").unbound(true);
        
        aCaminhoArquivo = new DomText();
        aCaminhoArquivo.context(ctx).name("CAMINHO_ARQUIVO").label("Caminho do arquivo").unbound(true);
        
    }
    
    @Override
    public String getDefaultOrderBy() {
        return "";
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="ARQUIVOS">
    public class FArquivos extends CustomFeature {
        
        @Override
        public void initForm() {
            aArquivo.setHidden(true);
            addField(aArquivo, "hidden");
            aDiretorio.setOptional(false);
            addField(aDiretorio, "rqd");
        }
        
        @Override
        public void preDisplay() {
            try {
                popularDiretorio();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void posDisplay() {
            try {
                montarTabela();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void onAction() {
            addSubmit(getFeature("NAVEGAR")).label("Navegar");
            addSubmit(getFeature("NAVEGAR_PASTA_WEB")).label("Pasta WEB");
            addSubmit(getFeature("NAVEGAR_PASTA_APPS")).label("Pasta APPS");
        }
        
        {
            setFeatureName("ARQUIVOS");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="VIEW">
    public class FView extends CustomFeature {
        
        @Override
        public void initForm() {
            aArquivo.setEditable(false);
            addField(aArquivo, "view");
            aNomeArquivo.setEditable(false);
            addField(aNomeArquivo, "view");
            aTamanho.setEditable(false);
            addField(aTamanho, "view");
            aDiretorio.setHidden(true);
            addField(aDiretorio, "hidden");
        }
        
        @Override
        public void preDisplay() {
            try {
                popularDadosArquivo();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void onAction() {
            addSubmit(getFeature("ARQUIVOS")).label("Voltar");
            addCancel(getFeature("DOWNLOAD")).label("Download");
            addCancel(getFeature("MOVER")).label("Mover");
            addCancel(getFeature("EXCLUIR")).label("Excluir").conf("Tem certeza que deseja excluir este arquivo?");
            addCancel(getFeature("RENOMEAR")).label("Renomear");
            addSubmit(getFeature("EDITAR")).label("Editar");
            addSubmit(getFeature("DESCOMPACTAR_ZIP")).label("Descompactar ZIP");
        }
        
        {
            setFeatureName("VIEW");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="MOVER">
    public class FMover extends CustomActionFeature {
        
        @Override
        public void initForm() {
            aArquivo.setEditable(false);
            addField(aArquivo, "view");
            aDestino.setOptional(false);
            addField(aDestino, "rqd");
        }
        
        @Override
        public void preDisplay() {
            try {
                popularCaminhoArquivo();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void onAction() {
            addCancel(getFeature("VIEW")).label("Cancelar");
        }
        
        @Override
        public void execute() {
            try {
                mover();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("MOVER");
            setTitle("Mover");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="RENOMEAR">
    public class FRenomear extends CustomActionFeature {
        
        @Override
        public void initForm() {
            aArquivo.setEditable(false);
            addField(aArquivo, "view");
            aNomeArquivo.setOptional(false);
            addField(aNomeArquivo, "rqd");
            aDiretorio.setHidden(true);
            addField(aDiretorio, "hidden");
        }
        
        @Override
        public void preDisplay() {
            try {
                popularNomeArquivo();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void onAction() {
            addCancel(getFeature("VIEW")).label("Cancelar");
        }
        
        @Override
        public void execute() {
            try {
                renomear();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("RENOMEAR");
            setTitle("Renomear");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="GERAR_ZIP">
    public class FGerarZip extends CustomFeature {
        
        @Override
        public void initForm() {
        }
        
        @Override
        public void execute() {
            try {
                gerarZip();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("GERAR_ZIP");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="UPLOAD">
    public class FUpload extends CustomActionFeature {
        
        @Override
        public void initForm() {
            aArquivo.setLabel("Destino");
            aArquivo.setEditable(false);
            addField(aArquivo, "view");
            aArquivoUpload.setOptional(false);
            addField(aArquivoUpload, "rqd");
            aDiretorio.setHidden(true);
            addField(aDiretorio, "hidden");
            addField(aSubstituirArquivo, "opt");
        }
        
        @Override
        public void preDisplay() {
            try {
                popularCaminhoArquivo();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void execute() {
            try {
                upload();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("UPLOAD");
            setActionTitle("Upload");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="EDITAR">
    public class FEditar extends CustomActionFeature {
        
        @Override
        public void initForm() {
            aArquivo.setEditable(false);
            addField(aArquivo, "view");
            aConteudoArquivo.setOptional(false);
            addField(aConteudoArquivo, "rqd");
            aDiretorio.setHidden(true);
            addField(aDiretorio, "hidden");
        }
        
        @Override
        public void preDisplay() {
            try {
                popularConteudoArquivo();
                popularCaminhoArquivo();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void onAction() {
            addCancel(getFeature("VIEW")).label("Cancelar").shortCutKey("ESC");
        }
        
        @Override
        public void execute() {
            try {
                editar();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("EDITAR");
            setActionTitle("Editar");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="DESCOMPACTAR_ZIP">
    public class FDescompactarZip extends CustomActionFeature {
        
        @Override
        public void initForm() {
            aArquivo.setEditable(false);
            addField(aArquivo, "view");
            aDestino.setOptional(false);
            addField(aDestino, "rqd");
        }
        
        @Override
        public void preDisplay() {
            try {
                popularDiretorioDestinoDescompactacao();
                popularCaminhoArquivo();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        @Override
        public void onAction() {
            addCancel(getFeature("VIEW")).label("Cancelar");
        }
        
        @Override
        public void execute() {
            try {
                descompactarZip();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("DESCOMPACTAR_ZIP");
            setTitle("Descompactar ZIP");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="NAVEGAR">
    public class FNavegar extends MethodFeature {
        
        @Override
        public void run() {
            preRun();
            try {
                navegar();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("NAVEGAR");
            setTitle("Navegar");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="NAVEGAR_PASTA_WEB">
    public class FNavegarPastaWeb extends MethodFeature {
        
        @Override
        public void run() {
            preRun();
            try {
                navegarPastaWeb();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("NAVEGAR_PASTA_WEB");
            setTitle("Navegar pasta WEB");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="NAVEGAR_PASTA_APPS">
    public class FNavegarPastaApps extends MethodFeature {
        
        @Override
        public void run() {
            preRun();
            try {
                navegarPastaApps();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("NAVEGAR_PASTA_APPS");
            setTitle("Navegar pasta apps");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="DOWNLOAD">
    public class FDownload extends MethodFeature {
        
        @Override
        public void run() {
            preRun();
            try {
                download();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("DOWNLOAD");
            setTitle("download");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="EXCLUIR">
    public class FExcluir extends MethodFeature {
        
        @Override
        public void run() {
            preRun();
            try {
                excluir();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("EXCLUIR");
            setTitle("Excluir");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="initFeatures">
    
    @Override
    protected void initFeatures() {
        addFeature(new FArquivos());
        addFeature(new FView());
        addFeature(new FMover());
        addFeature(new FRenomear());
        addFeature(new FGerarZip());
        addFeature(new FUpload());
        addFeature(new FEditar());
        addFeature(new FDescompactarZip());
        addFeature(new FNavegar());
        addFeature(new FNavegarPastaWeb());
        addFeature(new FNavegarPastaApps());
        addFeature(new FDownload());
        addFeature(new FExcluir());
        super.initFeatures();
    }
    
    @Override
    public String getDefaultFeature() {
        return "ARQUIVOS";
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Getters and Setters">
    
    public String getArquivo() {
        return aArquivo.getValue();
    }
    
    public void setArquivo(String value) {
        this.aArquivo.setValue(value);
    }
    
    public String getNomeArquivo() {
        return aNomeArquivo.getValue();
    }
    
    public void setNomeArquivo(String value) {
        this.aNomeArquivo.setValue(value);
    }
    
    public String getTamanho() {
        return aTamanho.getValue();
    }
    
    public void setTamanho(String value) {
        this.aTamanho.setValue(value);
    }
    
    public String getDestino() {
        return aDestino.getValue();
    }
    
    public void setDestino(String value) {
        this.aDestino.setValue(value);
    }
    
    public String getArquivoUpload() {
        return aArquivoUpload.getValue();
    }
    
    public void setArquivoUpload(String value) {
        this.aArquivoUpload.setValue(value);
    }
    
    public String getConteudoArquivo() {
        return aConteudoArquivo.getValue();
    }
    
    public void setConteudoArquivo(String value) {
        this.aConteudoArquivo.setValue(value);
    }
    
    public String getDiretorio() {
        return aDiretorio.getValue();
    }
    
    public void setDiretorio(String value) {
        this.aDiretorio.setValue(value);
    }
    
    public String getSubstituirArquivo() {
        return aSubstituirArquivo.getValue();
    }
    
    public void setSubstituirArquivo(String value) {
        this.aSubstituirArquivo.setValue(value);
    }
    
    public String getCaminhoArquivo() {
        return aCaminhoArquivo.getValue();
    }
    
    public void setCaminhoArquivo(String value) {
        this.aCaminhoArquivo.setValue(value);
    }
    // </editor-fold>
    
    /**
     * Mover.
     * <p>
     * Mover arquivo ou pasta de um diretório para outro
     */
    public void mover() throws AdsException {
        // <user-code id="6995948" parentId="6995947" hashcode="be2a8b4" length="1283">
        // import br.com.telescope.t2.exception.UnexpectedException;
        ctx.readFields(aArquivo);
        
        File file = new File(aArquivo.getValue());
        
        if (!file.exists()) {
            ctx.pushError(globalName("ARQUIVO_NAO_EXISTE"), Severity.ERROR, "Arquivo não encontrado!");
        } else {
            File destino = new File(aDestino.getValue());
            
            if (!destino.exists() || !destino.isDirectory()) {
                ctx.pushError(globalName("PASTA_DESTINO_INVALIDA"), Severity.ERROR, "Diretório de destino inválida ou não existe!");
                getFeature("MOVER").run();
            } else {
                
                try {
                    if (file.isDirectory()) {
                        org.apache.commons.io.FileUtils.moveDirectoryToDirectory(file, destino, false);
                    } else {
                        org.apache.commons.io.FileUtils.moveFileToDirectory(file, destino, false);
                    }
                    
                    ctx.showSuccess("Arquivo <strong>" + file.getName() + "</strong> movido para o diretório <strong>" + destino.getName() + "</strong> com sucesso");
        
                    if (destino.getParent() != null) {
                        ctx.setParameter("A_DIRETORIO", file.getParent());
                    }
                    getFeature("ARQUIVOS").run();
                } catch (IOException ex) {
                    ctx.pushError(ex);
                }
            }
        }
        // </user-code>
    }
    
    /**
     * Renomear.
     * <p>
     * Renomear arquivo ou pasta
     */
    public void renomear() throws AdsException {
        // <user-code id="6995954" parentId="6995953" hashcode="-367972ac" length="712">
        ctx.readFields(aArquivo, aNomeArquivo);
        
        File file = new File(aArquivo.getValue());
        
        if (!file.exists()) {
            ctx.pushError(globalName("ARQUIVO_NAO_EXISTE"), Severity.ERROR, "Arquivo não encontrado!");
        } else {
            File destino = new File(file.getParent(), aNomeArquivo.getValue());
            if (file.renameTo(destino)) {
                ctx.showSuccess((file.isDirectory() ? "Diretório" : "Arquivo") + " <strong>" + aArquivo.getValue() + "</strong> renomeado para <strong>" + destino.getAbsolutePath() + "</strong> com sucesso");
                
                if (file.getParent() != null) {
                    ctx.setParameter("A_DIRETORIO", file.getParent());
                }
                
                getFeature("ARQUIVOS").run();
            }
        }
        // </user-code>
    }
    
    /**
     * null.
     * <p>
     * Gera um zip recursivo da pasta selecionada
     */
    public void gerarZip() throws AdsException {
        // <user-code id="6996107" parentId="6996106" hashcode="6de738b5" length="672">
        // import br.com.telescope.util.ZipUtil;
        
        ctx.readFields(aDiretorio);
        
        File file = new File(aDiretorio.getValue());
        
        if (!file.exists()) {
            ctx.pushError(globalName("ARQUIVO_NAO_EXISTE"), Severity.ERROR, "Arquivo/Diretório não encontrado!");
        } else {
            String filename = file.getParent() + File.separator + file.getName() + ".zip";
            if (ZipUtil.zip(aDiretorio.getValue(), filename)) {
                ctx.showSuccess("ZIP gerado em <strong>" + filename + "</strong> com sucesso");
                if (file.getParent() != null) {
                    ctx.setParameter("A_DIRETORIO", file.getParent());
                }
                
                getFeature("ARQUIVOS").run();
            }
            
        }
        // </user-code>
    }
    
    /**
     * null.
     */
    public void upload() throws AdsException {
        // <user-code id="6996549" parentId="6996545" hashcode="562948ea" length="1542">
        ctx.readFields(aArquivo);
        
        File file = new File(aArquivo.getValue());
        
        if (!file.exists() || !file.isDirectory()) {
            ctx.pushError(globalName("ARQUIVO_NAO_EXISTE"), Severity.ERROR, "Arquivo não encontrado");
        } else {
            if (aArquivoUpload.isNotNull()) {
                try {
                    String[] files = aArquivoUpload.getValue().split("\\n");
                    
                    for (String f : files) {
                        String[] parts = f.split("\\|");
                        File tmp = new File(parts[0]);
        
                        if (aSubstituirArquivo.isTrue()) {
                            File e = new File(aArquivo.getValue(), parts[1]);
                            if (e.exists()) {
                                e.delete();
                            }
                        }
        
                        if (tmp.renameTo(new File(tmp.getParent(), parts[1]))) {
                            org.apache.commons.io.FileUtils.moveFileToDirectory(new File(tmp.getParent(), parts[1]), file, false);
        
                        }             
                    }
                    
                    if (files.length > 1) {
                        ctx.showSuccess(files.length + " arquivos enviados para <strong>" + aArquivo.getValue() + "</strong> com sucesso");
                    } else {
                        ctx.showSuccess("Arquivo enviado para <strong>" + aArquivo.getValue() + "</strong> com sucesso");
                    }
        
                    ctx.setParameter("A_DIRETORIO", aArquivo.getValue());
                    getFeature("ARQUIVOS").run();
                    
                } catch (IOException ex) {
                    ctx.pushError(ex);
                }
            }
        }
        // </user-code>
    }
    
    /**
     * null.
     * <p>
     * Interface para editar arquivo texto
     */
    public void editar() throws AdsException {
        // <user-code id="6996999" parentId="6996995" hashcode="-6be0df02" length="458">
        // import java.io.FileOutputStream;
        
        ctx.readFields(aArquivo, aConteudoArquivo);
        
        File file = new File(aArquivo.getValue());  
        FileOutputStream fos;  
        
        try {
            fos = new FileOutputStream(file);
            fos.write(aConteudoArquivo.getValue().getBytes());
            fos.close();
            
            ctx.showSuccess("Arquivo <strong>" + aArquivo.getValue() + "</strong> salvo com sucesso");
            
            getFeature("EDITAR").action("").run();
        } catch (Exception ex) {
        }
        // </user-code>
    }
    
    /**
     * Descompactar ZIP.
     */
    public void descompactarZip() throws AdsException {
        // <user-code id="7953090" parentId="7953089" hashcode="20053664" length="1018">
        ctx.readFields(aArquivo, aDestino);
        
        File file = new File(aArquivo.getValue());
        File destination = new File(aDestino.getValue());
        
        if (!destination.exists() || !destination.isDirectory()) {
            ctx.pushError(globalName("DESTINO_INVALIDO"), Severity.ERROR, "Diretório de destino inválido, favor verificar e tentar novamente!");
            getFeature("DESCOMPACTAR_ZIP").action("").run();
        } else {
            if (!file.exists()) {
                ctx.pushError(globalName("ARQUIVO_NAO_EXISTE"), Severity.ERROR, "Arquivo/Diretório não encontrado!");
                getFeature("DESCOMPACTAR_ZIP").action("").run();
            } else {
                try {
                    ZipUtil.unzip(aArquivo.getValue(), aDestino.getValue());
                    ctx.showSuccess("Arquivo <strong>" + aArquivo.getValue() + "</strong> descompactado com sucesso");
        
                    ctx.setParameter("A_DIRETORIO", aDestino.getValue());
                    getFeature("ARQUIVOS").run();
                } catch (Exception ex) {
                    throw new UnexpectedException(ex);
                }
            }
        }
        // </user-code>
    }
    
    /**
     * download.
     * <p>
     * Baixa um arquivo ou uma pasta especifica
     */
    private void download() throws AdsException {
        // <user-code id="6995941" parentId="6995940" hashcode="-268e7272" length="1029">
        // import br.com.telescope.util.FileUtil;
        // import br.com.telescope.util.MimeType;
        // import javax.servlet.ServletOutputStream;
        // import java.io.FileInputStream;
        
        ctx.readFields(aArquivo);
        
        File file = new File(aArquivo.getValue());
        
        if (!file.exists()) {
            ctx.pushError(globalName("ARQUIVO_NAO_EXISTE"), Severity.ERROR, "Arquivo não encontrado");
        } else {
        
            String ext = FileUtil.getExtension(file.getName());
            String mime = MimeType.getMimeType(ext);
            setShown(true);
            ctx.setContentType(mime);
            ctx.getHttpServletResponse().setHeader("content-disposition", "attachment; filename=" + file.getName());
            ServletOutputStream out = ctx.getOutputStream();
            
            try {
                FileInputStream fis = new FileInputStream(aArquivo.getValue());
        
                int c;
                byte[] buffer = new byte[16000];
                while ((c = fis.read(buffer)) >= 0) {
                    out.write(buffer, 0, c);
                }
                out.close();
            } catch (Exception ex) {
                ctx.pushError(ex);
            }
        }
        // </user-code>
    }
    
    /**
     * Excluir.
     * <p>
     * Excluir um arquivo ou uma pasta
     */
    private void excluir() throws AdsException {
        // <user-code id="6995946" parentId="6995945" hashcode="51f8bace" length="629">
        ctx.readFields(aArquivo);
        
        File file = new File(aArquivo.getValue());
        
        if (!file.exists()) {
            ctx.pushError(globalName("ARQUIVO_NAO_EXISTE"), Severity.ERROR, "Arquivo não encontrado");
        } else if (!file.isFile()) {
            ctx.pushError(globalName("ARQUIVO_NAO_FILE"), Severity.ERROR, "Não é possivel excluir um diretório");
        } else {
            if (file.delete()) {
                ctx.showSuccess("Arquivo <strong>" + file.getName() + "</strong> deletado com sucesso");
                if (file.getParent() != null) {
                    ctx.setParameter("A_DESTINO", file.getParent());   
                }
                getFeature("ARQUIVOS").run();
            }
        }
        // </user-code>
    }
    
    /**
     * montar tabela.
     * <p>
     * Monta uma tabela com lista de diretorios e arquivo dentro da pasta do 
     * campo diretorio
     */
    private void montarTabela() throws AdsException {
        // <user-code id="6995739" parentId="6995737" hashcode="1fb530cc" length="5280">
        // import br.com.telescope.t2.exception.Severity;
        // import br.com.telescope.util.TextUtil;
        // import br.com.telescope.t2.UserAction;
        // import java.text.SimpleDateFormat;
        // import br.com.telescope.t2.view.ActionRenderer;
        // import java.util.Arrays;
        // import java.util.Collections;
        
        ctx.readFields(aDiretorio);
        
        if (aDiretorio.isNull()) {
            aDiretorio.setValue(ctx.getServletContext().getRealPath("/"));
        }
        
        File file = new File(aDiretorio.getValue());
        
        if (!file.exists()) {
            ctx.pushError(globalName("DIRETORIO_NAO_ENCONTRADO"), Severity.ERROR, "Diretorio não encontrado");
        } else {
            File[] files = file.listFiles(); 
            int total = files.length;
            int end = 100;
            int page = ctx.getParameter("Z_PAGE").isEmpty() ? 1 : Integer.parseInt(ctx.getParameter("Z_PAGE"));
            int start = (page - 1) * 100 + 1;
            int totalPages = (total / end) + 1;
            
            if (total < end) {
                end = total;
            } else if (totalPages == page) {
                end = total - (totalPages - 1) * end;
            }
            
            Collections.sort(Arrays.asList(files));
            
            ctx.p("<h2>Arquivos</h2><div class=\"table-container\"><table class=\"list\"><thead><tr><th width=\"70%\">Arquivos</th><th>Tamanho</th><th>Data de modificação</th></tr></thead><tbody>");
            
            if (file.getParent() != null) {
                ctx.p("<tr><td><a href=\"UtlFiles?Z_ACTION=ARQUIVOS&A_DIRETORIO=" + file.getParent() + "\">..</a></td><td></td><td></td></tr>");
            }
            
            for (int i = 0; i < end; i++) {
                File f = files[(start-1)+i];
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
                if (f.isDirectory()) {
                    ctx.p("<tr><td><a href=\"UtlFiles?Z_ACTION=ARQUIVOS&A_DIRETORIO=" + f.getAbsolutePath() + "\">" + f.getName()  + "</a></td><td></td><td>" + sdf.format(f.lastModified()) + "</td></tr>");
                } else if (f.isFile()) {
                    ctx.p("<tr>");
                    ctx.p("<td><a href=\"UtlFiles?Z_ACTION=VIEW&A_ARQUIVO=" + f.getAbsolutePath() + "\">" + f.getName()  + "</a></td>");
                    ctx.p("<td>" + TextUtil.toReadableSize(f.length()) + "</td>");
                    ctx.p("<td>" + sdf.format(f.lastModified()) + "</td>");
                    ctx.append("</tr>");
                }
            }
        
            ctx.p("<tr class=\"records disabled\"><td colspan=\"3\">" + start + " a " + (totalPages == page ? total : page * end) + " de " + total + "</td></tr></tbody></table></div>");
            
            UserAction download = new UserAction();
            download.label("Gerar ZIP")
                    .form(getForm())
                    .formName(getCurrentFeature().getFeatureFormName())
                    .action("GERAR_ZIP:SUBMIT")
                    .submit(false);
            
            UserAction renomear = new UserAction();
            renomear.label("Renomear diretório")
                    .form(getForm())
                    .formName(getCurrentFeature().getFeatureFormName())
                    .action("RENOMEAR")
                    .submit(false);
            renomear.addParameter("A_ARQUIVO", aDiretorio.getValue());
            
            UserAction mover = new UserAction();
            mover.label("Mover diretório")
                    .form(getForm())
                    .formName(getCurrentFeature().getFeatureFormName())
                    .action("MOVER")
                    .submit(false);
            mover.addParameter("A_ARQUIVO", aDiretorio.getValue());
            
            UserAction upload = new UserAction();
            upload.label("Upload de arquivo")
                    .form(getForm())
                    .formName(getCurrentFeature().getFeatureFormName())
                    .action("UPLOAD")
                    .submit(false);
            upload.addParameter("A_ARQUIVO", aDiretorio.getValue());
        
            UserAction first = new UserAction();
            first.label("<<")
                    .form(getForm())
                    .formName(getCurrentFeature().getFeatureFormName())
                    .action("ARQUIVOS")
                    .parameter("Z_PAGE", "1")
                    .submit(false);
            first.setEnable(page > 1);
            
            UserAction previus = new UserAction();
            previus.label("<")
                    .form(getForm())
                    .formName(getCurrentFeature().getFeatureFormName())
                    .action("ARQUIVOS")
                    .parameter("Z_PAGE", page - 1)
                    .submit(false);
            previus.setEnable(page > 1);
            
            UserAction next = new UserAction();
            next.label(">")
                    .form(getForm())
                    .formName(getCurrentFeature().getFeatureFormName())
                    .action("ARQUIVOS")
                    .parameter("Z_PAGE", page + 1)
                    .submit(false);
            next.setEnable(page < totalPages);
            
            UserAction last = new UserAction();
            last.label(">>")
                    .form(getForm())
                    .formName(getCurrentFeature().getFeatureFormName())
                    .action("ARQUIVOS")
                    .parameter("Z_PAGE", totalPages)
                    .submit(false);
            last.setEnable(page < totalPages);
            
            ActionRenderer renderer = ctx.getRendererFactory().getActionRenderer();
            ctx.p("<div class=\"form-actions\">");
            ctx.p(renderer.render(download) 
                    + renderer.render(renomear) 
                    + renderer.render(mover) 
                    + renderer.render(upload)
                    + renderer.render(first)
                    + renderer.render(previus) 
                    + renderer.render(next)
                    + renderer.render(last));
            ctx.p("</div>");
        }
        // </user-code>
    }
    
    /**
     * Navegar.
     */
    private void navegar() throws AdsException {
        // <user-code id="22249223" parentId="22249222" hashcode="6a45cd90" length="149">
        ctx.readFields(aDiretorio);
        ctx.setParameter("Z_PAGE", "1");
        ctx.setParameter("A_DIRETORIO", aDiretorio.getValue());
        getFeature("ARQUIVOS").run();
        // </user-code>
    }
    
    /**
     * Navegar pasta apps.
     * <p>
     * Redireciona para pasta APPS onde contém arquivo de anexos e arquivos 
     * do TLU.
     */
    private void navegarPastaApps() throws AdsException {
        // <user-code id="9538951" parentId="9538950" hashcode="-5966563d" length="181">
        // import br.com.telescope.t2.config.Config;
        ctx.setParameter("Z_PAGE", "1");
        ctx.setParameter("A_DIRETORIO", Config.getInstance().getConfigPath());
        getFeature("ARQUIVOS").run();
        // </user-code>
    }
    
    /**
     * Navegar pasta WEB.
     * <p>
     * Redireciona para pasta WEB onde contém arquivos de web, js, reports 
     * ...
     */
    private void navegarPastaWeb() throws AdsException {
        // <user-code id="9538955" parentId="9538954" hashcode="c7efb6b" length="139">
        ctx.setParameter("Z_PAGE", "1");
        ctx.setParameter("A_DIRETORIO", ctx.getServletContext().getRealPath("/"));
        getFeature("ARQUIVOS").run();
        // </user-code>
    }
    
    /**
     * Popular caminho arquivo.
     */
    private void popularCaminhoArquivo() throws AdsException {
        // <user-code id="6995974" parentId="6995972" hashcode="-34f34870" length="25">
        ctx.readFields(aArquivo);
        // </user-code>
    }
    
    /**
     * Popular conteudo arquivo.
     */
    private void popularConteudoArquivo() throws AdsException {
        // <user-code id="6996997" parentId="6996996" hashcode="1e4bdba5" length="433">
        ctx.readFields(aArquivo, aDiretorio);
        
        try {
            BufferedReader in = new BufferedReader(new FileReader(aArquivo.getValue()));
            StringBuilder value = new StringBuilder(2000);
            while (in.ready()) {
                if (value.length() > 0) {
                    value.append("\n");
                }
                value.append(in.readLine());
            }
            in.close();
            
            aConteudoArquivo.setValue(value.toString());
        } catch (IOException e) {
        }
        // </user-code>
    }
    
    /**
     * Popular dados arquivo.
     * <p>
     * Popula dados do arquivo para visualização
     */
    private void popularDadosArquivo() throws AdsException {
        // <user-code id="6995782" parentId="6995779" hashcode="1d5e7e2f" length="576">
        ctx.readFields(aArquivo);
        
        File file = new File(aArquivo.getValue());
        
        if (!file.exists()) {
            ctx.pushError(globalName("ARQUIVO_NAO_EXISTE"), Severity.ERROR, "Arquivo não encontrado");
        } else if (!file.isFile()) {
            ctx.pushError(globalName("ARQUIVO_NAO_FILE"), Severity.ERROR, "Arquivo não é válido");
        } else {
            aDiretorio.setValue(file.getParent());
            aNomeArquivo.setValue(file.getName());
            aCaminhoArquivo.setValue(file.getAbsolutePath());
            aTamanho.setValue(TextUtil.toReadableSize(file.length()));
            aDestino.setValue(file.getParent());
        }
        // </user-code>
    }
    
    /**
     * Popular diretório.
     * <p>
     * Caso nenhum diretório/caminho for informado assume como o da aplicação
     */
    private void popularDiretorio() throws AdsException {
        // <user-code id="6995756" parentId="6995754" hashcode="5b9528bd" length="383">
        // import br.com.telescope.adsrt.dom.DomInteger;
        ctx.readFields(aDiretorio);
        
        Field page = new DomInteger();
        page.context(ctx)
                .hidden(true)
                .value(ctx.getParameter("Z_PAGE", "1"))
                .name("PAGE")
                .control(true);
                
        getForm().add(page);
        
        if (aDiretorio.isNull()) {
            aDiretorio.setValue(ctx.getServletContext().getRealPath("/"));
        }
        // </user-code>
    }
    
    /**
     * Popular diretório destino para descompactação.
     * <p>
     * Preenche o campo destino com uma sugestão de caminho para 
     * descompactação do mesmo.
     */
    private void popularDiretorioDestinoDescompactacao() throws AdsException {
        // <user-code id="10908142" parentId="10908139" hashcode="678f49c" length="113">
        ctx.readFields(aArquivo);
        File file = new File(aArquivo.getValue());
        aDestino.setValue(file.getParent() + "/");
        // </user-code>
    }
    
    /**
     * Popular nome arquivo.
     */
    private void popularNomeArquivo() throws AdsException {
        // <user-code id="6995980" parentId="6995978" hashcode="778a237e" length="344">
        ctx.readFields(aArquivo);
        
        File file = new File(aArquivo.getValue());
        
        if (!file.exists()) {
            ctx.pushError(globalName("ARQUIVO_NAO_EXISTE"), Severity.ERROR, "Arquivo/Diretório não encontrado");
        } else {
            aNomeArquivo.setLabel("Novo nome");
            aNomeArquivo.setValue(file.getName());
            aArquivo.setLabel("Caminho original");
        }
        // </user-code>
    }
}
